package com.ttxs.generator.util;

import com.fasterxml.jackson.core.type.TypeReference;
import com.ttxs.generator.remote.RemoteResponse;
import com.ttxs.generator.remote.dto.AbstractDTO;
import com.ttxs.generator.vo.Token;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import static com.ttxs.generator.remote.RemoteContants.Header.*;

@Slf4j
public class RestTemplateUtils {

    private static RestTemplate restTemplate = new RestTemplate();

    public static <T> T post(AbstractDTO dto, Class<T> responseType, Object... uriVariables) {

        RemoteResponse remoteResponse = restTemplate.postForObject(dto.getUrl(), createEntity(dto), RemoteResponse.class, uriVariables);
        return ObjectMapperUtils.convert(remoteResponse.getData(), responseType);
    }

    public static <T> T postForm(AbstractDTO dto, Class<T> responseType, Object... uriVariables) {
        RemoteResponse remoteResponse = restTemplate.postForObject(dto.getUrl(), createFormEntity(dto), RemoteResponse.class, uriVariables);
        return ObjectMapperUtils.convert(remoteResponse.getData(), responseType);
    }

    public static <T> T get(AbstractDTO dto, Class<T> responseType, Object... uriVariables) {
        ResponseEntity<RemoteResponse> exchange = restTemplate.exchange(dto.getUrl(), HttpMethod.GET, createEntity(dto), RemoteResponse.class, uriVariables);
        return ObjectMapperUtils.convert(exchange.getBody().getData(), responseType);
    }

    public static <T> T get(AbstractDTO dto, TypeReference<T> responseType, Object... uriVariables) {
        ResponseEntity<RemoteResponse> exchange = restTemplate.exchange(dto.getUrl(), HttpMethod.GET, createEntity(dto), RemoteResponse.class, uriVariables);
        return ObjectMapperUtils.convert(exchange.getBody().getData(), responseType);
    }

    public static HttpEntity<?> createFormEntity(AbstractDTO dto) {
        HttpHeaders headers = createHeaders(dto.getToken());
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        return new HttpEntity(ObjectMapperUtils.toMultiValueMap(dto), headers);
    }

    public static HttpEntity<?> createEntity(AbstractDTO dto) {
        return new HttpEntity(ObjectMapperUtils.toMap(dto), createHeaders(dto.getToken()));
    }

    public static HttpHeaders createHeaders(Token token) {
        HttpHeaders headers = new HttpHeaders();
        if (token != null) {
            headers.add(TOKEN, token.getToken());
            headers.add(AUTHORIZATION, "Bearer " + token.getToken());
            headers.add(PLATFORM_ID, token.getPlatformId());
            headers.add(USER_ID, token.getUserId().toString());
            headers.add(PLATFORM_NAME, token.getPlatformName());
            try {
                headers.add(ROLE_NAMES, URLEncoder.encode(token.getRoleNames(), "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                log.error(e.getMessage(), e);
            }
        }
        return headers;
    }
}
